﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using SharingCenter.Web.Classes;
using SharingCenter.Web.Classes.enums;
using SharingCenter.Web.Shared;

namespace SharingCenter.Web.User.Message
{
    using SharingCenter.Web.Classes.Contact;
    using SharingCenter.Web.Classes.Requests;
    using SharingCenter.Web.Classes;
    using SharingCenter.Web.Classes.enums;
    using SharingCenter.Web.Classes.Messages;
    using SharingCenter.Web.Classes.Learning;
    using System.Xml.Linq;
    using System.Reflection;
    using System.Xml;
    using System.Xml.Xsl;
    using System.IO;
    using System.Text;
    using System.Xml.XPath;

    public partial class Requests : MessagePageBase
    {
        ListViewItemEventArgs _curBoundArgs;
        List<Sc_SharedRequest> _reqList;

        public override void VerifyRenderingInServerForm(System.Web.UI.Control Control){}

        protected void Page_Init(object sender, EventArgs e)
        {
            using (scDataContext cxt = new scDataContext())
            {
                _reqList = cxt.GetRequestByRecipientUserId(Profile.UserId).ToList();
            }
            LinqDataSource1.Selecting += new EventHandler<LinqDataSourceSelectEventArgs>(LinqDataSource1_Selecting);
            ListView1.ItemDataBound += new EventHandler<ListViewItemEventArgs>(ListView1_ItemDataBound);
            ListView1.ItemCommand += new EventHandler<ListViewCommandEventArgs>(ListView1_ItemCommand);
            ListView1.DataBinding += new EventHandler(ListView1_DataBinding);
        }

        void ListView1_DataBinding(object sender, EventArgs e)
        {
            
        }

        void ListView1_ItemCommand(object sender, ListViewCommandEventArgs e)
        {
            Guid rid = new Guid(ListView1.DataKeys[((ListViewDataItem)e.Item).DataItemIndex].Value.ToString());
            Sc_SharedRequest rq = RequestOperations.GetRequestById(rid);
            
        }

        void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
        {
            if (e.Item.ItemType == ListViewItemType.DataItem)
            {
                _curBoundArgs = e;
                Sc_SharedRequest request = (Sc_SharedRequest)((ListViewDataItem)e.Item).DataItem;
                //SwtichEntityView(request.ContextType);
                Panel p = (Panel)e.Item.FindControl("pnRequest");
                TransformContext(ref request, ref p);
            }
        }

        private void TransformContext(ref Sc_SharedRequest request, ref Panel p)
        {
            string entity = request.ContextType.ToString();
            request.Context.Add(new XElement("RequestId", request.RequestId));
            ClassLibrary.StringHelper h = new ClassLibrary.StringHelper(request.Context.ToString());
            XAttribute folderAttr = request.Context.Attribute("XsltFolderInMod");
            XElement trans = XElement.Parse(ConvertXml(h.AsMemoryStream, folderAttr == null ? entity : folderAttr.Value));
            XElement contentToRender = trans.XPathSelectElement("ContentToRender/Template[@status='" + request.Status + "']/Content");

            RegisterClientScripts(trans.XPathSelectElement("ContentToRender/Template[@status='" + request.Status + "']/Scripts"));
            // find user controls
            try
            {
                List<XElement> ctrlList = contentToRender.Descendants("control").ToList();
                foreach (XElement c in ctrlList)
                {
                    string renderedHtml = string.Empty;
                    switch (c.Attribute("kind").Value.ToLower())
                    {
                        case "usercontrol":
                            renderedHtml = RenderUserControl(c, Type.GetType(c.Attribute("type").Value), ref p);
                            break;
                        case "userlink":
                            renderedHtml = RenderUserLink(c);
                            break;
                        case "servercontrol":
                            break;
                    }

                    c.ReplaceWith(XElement.Parse(renderedHtml));
                }
            }
            catch { }

            Literal l = new Literal();
            l.Text = "<div class='reqitembox'>" + ClassLibrary.LinqToXmlHelper.GetInnerXml(contentToRender) + "</div>";
            p.Controls.Add(l);
        }

        void RegisterClientScripts(XElement script)
        {
            try
            {
                foreach (XElement block in script.Elements("Block"))
                {
                    if (!ClientScript.IsClientScriptBlockRegistered(block.Attribute("name").Value))
                    {
                        ClientScript.RegisterClientScriptBlock(this.GetType(), block.Attribute("name").Value, ClassLibrary.LinqToXmlHelper.GetInnerXml(block));
                    }
                }
            }
            catch { }
        }

        private string RenderUserLink(XElement c)
        {
            Guid userId = new Guid(c.Attribute("UserId").Value);
            NickNameLink lnk = new NickNameLink();
            lnk.UserId = userId;
            StringBuilder sb = new StringBuilder();
            StringWriter tw = new StringWriter(sb);
            HtmlTextWriter hw = new HtmlTextWriter(tw);
            lnk.RenderControl(hw);

            return sb.ToString();
        }

        string RenderUserControl(XElement e, Type t, ref Panel pn)
        {
            string controlPath = string.Format("~/{0}/{1}", e.Attribute("location").Value, e.Attribute("name").Value);

            ClassLibrary.ViewManager<UserControl> viewManager = new ClassLibrary.ViewManager<UserControl>();
            //UserControl c = new UserControl();
            Control control = viewManager.LoadViewControl(controlPath);
            
            foreach (XElement p in e.Descendants("property"))
            {
                string attrName = p.Attribute("name").Value;
                PropertyInfo info = t.GetProperty(attrName);

                object value;
                if (p.Attribute("type").Value == "System.Guid")
                {
                    value = new Guid(p.Attribute("value").Value);
                }
                else
                {
                    Type valueType = Type.GetType(p.Attribute("type").Value);
                    value = Convert.ChangeType(p.Attribute("value").Value, valueType);
                }
               
                info.SetValue(control, value, null);
            }

            
            StringBuilder sb = new StringBuilder();
            StringWriter tw = new StringWriter(sb);
            HtmlTextWriter hw = new HtmlTextWriter(tw);
            
            //control.RenderControl(hw);
            //return sb.ToString();
            return viewManager.RenderView((UserControl)control); 
        }

        void control_PreRender(object sender, EventArgs e)
        {
            sender = null;
        }

        string ConvertXml(Stream xml, string entity)
        {
            string result = string.Empty;

            // load XML from file
            StreamReader sr = new StreamReader(xml);
            XPathDocument myXPathDoc = new XPathDocument(sr);

            // load XSL from file
            XslCompiledTransform xslt = new XslCompiledTransform();
            xslt.Load(Server.MapPath(string.Format(@"~/Mod/{0}/RequestContextTransform.xslt", entity)));

            XsltArgumentList xslArg = new XsltArgumentList();
            xslArg.AddParam("relrootpath", "", HttpRuntime.AppDomainAppVirtualPath == "/" ? "" : HttpRuntime.AppDomainAppVirtualPath);

            // memory stream that will hold the transformation
            MemoryStream htmlOutput = new MemoryStream();

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true;
            settings.ConformanceLevel = ConformanceLevel.Fragment;
            settings.Encoding = Encoding.UTF8;

            // XML Writter user to write to the memory stream
            XmlWriter writterOut = XmlWriter.Create(htmlOutput, settings);

            // run the ransformation
            xslt.Transform(myXPathDoc, xslArg, writterOut);

            // make sure everything gets pushed to the memory stream
            writterOut.Flush();

            // go to the start of the memory stream
            htmlOutput.Position = 0;

            // read from the memory stream
            StreamReader strm = new StreamReader(htmlOutput, Encoding.UTF8);

            // read the stream to text reader
            using (TextReader txtRead = strm)
            {
                result = txtRead.ReadToEnd();
            }

            return result;
        }

        void LinqDataSource1_Selecting(object sender, LinqDataSourceSelectEventArgs e)
        {
            e.Result = _reqList;
        }
    }
}
